package com.data.modules.quartz.job;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.data.common.api.vo.CrmResult;
import com.data.common.constant.CommonConstant;
import com.data.common.exception.BootException;
import com.data.common.util.ConvertUtils;
import com.data.common.util.PasswordUtil;
import com.data.modules.feign.AdminService;
import com.data.modules.system.entity.SysUser;
import com.data.modules.system.entity.SysUserDepart;
import com.data.modules.system.mapper.SysUserMapper;
import com.data.modules.system.service.ISysUserDepartService;
import com.data.modules.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * CrmOrgJob 同步crm 组织机构到 databoot
 * </p>
 *
 * @author li
 * @version 1.0
 * @date 2022-02-25 15:12
 * @since 1.0
 */
@Slf4j
@Component
public class CrmOrgJob implements Job {

    /**
     * 若参数变量名修改 QuartzJobController中也需对应修改
     */
    private String parameter;

    public void setParameter(String parameter) {
        this.parameter = parameter;
    }

    /**
     * 公共密码
     */
    @Value("${hlcrm.login.pubiicPassWord:}")
    private String pubiicPassWord;

    @Autowired
    @Lazy
    private AdminService adminService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private ISysUserDepartService userDepartService;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("同步crm 组织机构到 databoot param={}", parameter);
        getMonth(parameter).forEach(this::executeTask);
        log.info("同步crm 组织机构到 databoot 同步完成");
    }

    private List<String> getMonth(String parameter) {
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM");
        if (StringUtils.isBlank(parameter)) {
            return Stream.of(LocalDate.now().format(pattern)).collect(Collectors.toList());
        }else {
            return Arrays.asList(parameter);
        }
        /*String start = parameter.split(",")[0];
        String end = parameter.split(",")[1];
        Function<String, String> date = month -> month + "-01";
        LocalDate startDate = LocalDate.parse(date.apply(start));
        LocalDate endDate = LocalDate.parse(date.apply(end));
        long distance = ChronoUnit.MONTHS.between(startDate, endDate);
        return Stream.iterate(startDate, d -> d.plusMonths(1)).limit(distance + 1)
                .map(k->k.format(pattern))
                .peek(System.out::println)
                .collect(Collectors.toList());*/
    }

    private void executeTask(String month) {
        List<JSONObject> list = null;
        try {
            log.info("同步crm 组织机构到 databoot crm param={}", month);
            CrmResult<List<JSONObject>> result = adminService.queryRpUserStatusList(month);
            log.info("同步crm 组织机构到 databoot crm result={}", JSONObject.toJSONString(result));
            list = result.getData();
            if (CollectionUtil.isEmpty(list)) {
                return;
            }
        } catch (Exception e) {
            log.info("同步crm 组织机构到 databoot crm 调用失败",e);
            throw new BootException("同步crm 组织机构到 databoot crm 调用失败");
        }
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<SysUser>().select(SysUser::getId, SysUser::getPhone);
        List<SysUser> sysUsers = userMapper.selectLogicDeleted(wrapper);
        Map<String, String> userIdMap = sysUsers.stream().map(SysUser::getId).collect(Collectors.toMap(Function.identity(), Function.identity()));
        Map<String, String> userPhoneMap = sysUsers.stream().filter(k -> Objects.nonNull(k.getPhone())).map(SysUser::getPhone).collect(Collectors.toMap(Function.identity(), Function.identity()));

        for (JSONObject data : list) {
            SysUser user = new SysUser();
            String userId = data.get("userId").toString();
            String deptId = data.get("deptId").toString();
            //手机号
            String mobile = data.getString("mobile");
            if (Objects.isNull(userIdMap.get(userId))) {
                //将此次登录的用户信息保存到DTO中，后面会用到
                user.setId(userId);//用户ID
            }
            user.setId(userId);//用户ID
            user.setPhone(data.getString("mobile"));
            user.setUsername(data.getString("username"));//用户登陆名称
            //adminDTO.setPassword(data.getString("password"));//密码,暂时不用密码，只能单点登陆过来
            user.setRealname(data.getString("realname"));//真实名称
            user.setAvatar(data.getString("img"));//图像地址
            user.setDelFlag(0);
            user.setCreateTime(new Date());
            user.setCreateBy("");
            String salt = ConvertUtils.randomGen(8);
            user.setSalt(salt);
            String passwordEncode = PasswordUtil.encrypt(user.getUsername(), pubiicPassWord, salt);
            user.setPassword(passwordEncode);
            user.setStatus(1);
            user.setDelFlag(CommonConstant.DEL_FLAG_0);

            //更新 or 新增
            if (Objects.nonNull(userPhoneMap.get(user.getPhone()))) {
                user.setId(null);
                userService.lambdaUpdate().eq(SysUser::getPhone, user.getPhone()).update(user);
                continue;
            }
            if (Objects.nonNull(userIdMap.get(user.getId()))) {
                userService.updateById(user);
                continue;
            }
            userService.save(user);
        }

        //user dept 更新 or 新增
        List<String> userIds = list.stream().map(data -> data.get("userId").toString()).collect(Collectors.toList());
        List<SysUserDepart> departs = userDepartService.lambdaQuery().in(SysUserDepart::getUserId, userIds).list();
        Map<String, SysUserDepart> departMap = departs.stream().collect(Collectors.toMap(SysUserDepart::getUserId, Function.identity()));
        List<SysUserDepart> userDepartList = list.stream().map(data -> {
            String userId = data.get("userId").toString();
            String deptId = data.get("deptId").toString();
            SysUserDepart userDepart = Optional.ofNullable(departMap.get(userId)).orElse(new SysUserDepart(userId, deptId));
            userDepart.setDepId(deptId);
            return userDepart;
        }).collect(Collectors.toList());

        userDepartService.saveOrUpdateBatch(userDepartList);
    }

}
